home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / NEW_TECH / NTUNZ2.ZIP / NT.C < prev    next >
C/C++ Source or Header  |  1993-12-19  |  41KB  |  1,097 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   nt.c
  4.  
  5.   WinNT-specific routines for use with Info-ZIP's UnZip 5.1 and later.
  6.  
  7.  
  8.   1993-09-28 Henry Gessau <henryg@kullmar.kullmar.se>
  9.   Started hacking at this. Borrowed, pilfered and plundered code from OS/2
  10.   and MS-DOS versions and from ZIP, modifying as necessary.
  11.  
  12.   Last updated: 19 Dec 1993
  13.  
  14.   ---------------------------------------------------------------------------*/
  15.  
  16. #include <windows.h>
  17. #include "unzip.h"
  18.  
  19.  
  20. #define MKDIR(path,mode)   mkdir(path)
  21.  
  22. struct direct
  23. {
  24.     char    reserved [21];
  25.     char    ff_attrib;
  26.     short   ff_ftime;
  27.     short   ff_fdate;
  28.     long    size;
  29.     char    d_name[MAX_PATH];
  30.     int     d_first;
  31.     HANDLE  d_hFindFile;
  32. };
  33.  
  34.  
  35. static int created_dir;         /* used by mapname(), checkdir() */
  36. static int renamed_fullpath;    /* ditto */
  37. static int fnlen;               /* ditto */
  38. static unsigned nLabelDrive;    /* ditto */
  39.  
  40.  
  41.  
  42. /**********************/        /* Borrowed from ZIP 2.0 sources             */
  43. /* Function opendir() */        /* Difference: no special handling for       */
  44. /**********************/        /*             hidden or system files.       */
  45.  
  46. static struct direct *opendir(n)
  47.     const char *n;  /* directory to open */
  48. {
  49.     struct direct *d;       /* malloc'd return value */
  50.     char *p;                /* malloc'd temporary string */
  51.     WIN32_FIND_DATA fd;
  52.  
  53.     /* Start searching for files in the MSDOS directory n */
  54.  
  55.     if ( (d = (struct direct *)malloc(sizeof(struct direct))) == NULL ||
  56.          (p = malloc(strlen(n) + 5)) == NULL                             )
  57.     {
  58.         if ( d != NULL )
  59.             free((void *) d);
  60.         return NULL;
  61.     }
  62.     strcat(strcpy(p, n), "/*.*");
  63.  
  64.     if ( INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd)) )
  65.     {
  66.         free((voidp *)d);
  67.         free((voidp *)p);
  68.         return NULL;
  69.     }
  70.     strcpy(d->d_name, fd.cFileName);
  71.  
  72.     free((voidp *)p);
  73.     d->d_first = 1;
  74.     return d;
  75.  
  76. } /* end of function opendir() */
  77.  
  78.  
  79.  
  80.  
  81. /**********************/        /* Borrowed from ZIP 2.0 sources             */
  82. /* Function readdir() */        /* Difference: no special handling for       */
  83. /**********************/        /*             hidden or system files.       */
  84.  
  85. static struct direct *readdir(d)
  86.     struct direct *d;         /* directory stream from which to read */
  87. {
  88.     /* Return pointer to first or next directory entry, or NULL if end. */
  89.  
  90.     if ( d->d_first )
  91.         d->d_first = 0;
  92.     else
  93.     {
  94.         WIN32_FIND_DATA fd;
  95.  
  96.         if ( !FindNextFile(d->d_hFindFile, &fd) )
  97.             return NULL;
  98.  
  99.         strcpy(d->d_name, fd.cFileName);
  100.     }
  101.     return (struct direct *)d;
  102.  
  103. } /* end of function readdir() */
  104.  
  105.  
  106.  
  107.  
  108. /***********************/
  109. /* Function closedir() */       /* Borrowed from ZIP 2.0 sources */
  110. /***********************/
  111.  
  112. static void closedir(d)
  113.     struct direct *d;         /* directory stream to close */
  114. {
  115.     FindClose(d->d_hFindFile);
  116.     free(d);
  117. }
  118.  
  119.  
  120.  
  121.  
  122. /**********************/
  123. /* Function mapattr() */
  124. /**********************/
  125.  
  126. /* Identical to MS-DOS, OS/2 versions.                                       */
  127. /* However, NT has a lot of extra permission stuff, so this function should  */
  128. /*  probably be extended in the future.                                      */
  129.  
  130. int mapattr()
  131. {
  132.     /* set archive bit (file is not backed up): */
  133.     pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;
  134.     return 0;
  135.  
  136. } /* end function mapattr() */
  137.  
  138.  
  139.  
  140.  
  141. /****************************/      /* Get the file time in a format that */
  142. /* Function getNTfiletime() */      /* can be used by SetFileTime() in NT */
  143. /****************************/
  144.  
  145. int getNTfiletime(FILETIME *ft)
  146. {
  147.     FILETIME lft;      /* 64-bit value made up of two 32 bit [low & high] */
  148.     WORD wDOSDate;     /* for converting from DOS date to Windows NT      */
  149.     WORD wDOSTime;
  150.  
  151.     /* Copy and/or convert time and date variables, if necessary;   */
  152.     /* then set the file time/date.                                 */
  153.     wDOSTime = (WORD)lrec.last_mod_file_time;
  154.     wDOSDate = (WORD)lrec.last_mod_file_date;
  155.  
  156.     /* The DosDateTimeToFileTime() function converts a DOS date/time    */
  157.     /* into a 64 bit Windows NT file time                               */
  158.     if (!DosDateTimeToFileTime(wDOSDate, wDOSTime, &lft))
  159.     {
  160.         printf("DosDateTime failed: %d\n", GetLastError());
  161.         return FALSE;
  162.     }
  163.     if (!LocalFileTimeToFileTime( &lft, ft))
  164.     {
  165.         printf("LocalFileTime failed: %d\n", GetLastError());
  166.         *ft = lft;
  167.     }
  168.     return TRUE;
  169. }
  170.  
  171.  
  172.  
  173.  
  174. /****************************/
  175. /* Function close_outfile() */
  176. /****************************/
  177.  
  178. void close_outfile()
  179. {
  180.     FILETIME ft;       /* File time type defined in NT */
  181.     HANDLE hFile;      /* File handle defined in NT    */
  182.     int gotTime;
  183.  
  184.     /* don't set the time stamp on standard output */
  185.     if (cflag) {
  186.         fclose(outfile);
  187.         return;
  188.     }
  189.  
  190.     gotTime = getNTfiletime(&ft);
  191.  
  192.     /* Close the file and then re-open it using the Win32
  193.      * CreateFile call, so that the file can be created
  194.      * with GENERIC_WRITE access, otherwise the SetFileTime
  195.      * call will fail. */
  196.     fclose(outfile);
  197.  
  198.     hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
  199.          FILE_ATTRIBUTE_NORMAL, NULL);
  200.     if ( hFile == INVALID_HANDLE_VALUE ) {
  201.         fprintf(stderr, "\nCreateFile error %d when trying set file time\n",
  202.                 GetLastError());
  203.     }
  204.     else {
  205.         if (gotTime)
  206.             if (!SetFileTime(hFile, NULL, NULL, &ft))
  207.                 printf("\nSetFileTime failed: %d\n", GetLastError());
  208.         CloseHandle(hFile);
  209.     }
  210.  
  211.     /* HG: I think this could be done in the CreateFile call above - just  */
  212.     /*     replace 'FILE_ATTRIBUTE_NORMAL' with 'pInfo->file_attr & 0x7F'  */
  213.     if (!SetFileAttributes(filename, pInfo->file_attr & 0x7F))
  214.         fprintf(stderr, "\nwarning (%d): could not set file attributes\n",
  215.                 GetLastError());
  216.  
  217.     return;
  218.  
  219. } /* end function close_outfile() */
  220.  
  221.  
  222.  
  223. /* ============================================================================
  224. */
  225.  
  226.  
  227.  
  228. /***********************/
  229. /* Function isfloppy() */   /* more precisely, is it removable? */
  230. /***********************/
  231.  
  232. static int isfloppy(int nDrive)   /* 1 == A:, 2 == B:, etc. */
  233. {
  234.     char rootPathName[4];
  235.  
  236.     rootPathName[0] = 'A' + nDrive - 1;   /* Build the root path name, */
  237.     rootPathName[1] = ':';                /* e.g. "A:/"                */
  238.     rootPathName[2] = '/';
  239.     rootPathName[3] = '\0';
  240.  
  241.     if ( GetDriveType(rootPathName) == DRIVE_REMOVABLE )
  242.         return TRUE;
  243.     else
  244.         return FALSE;
  245.  
  246. } /* end function isfloppy() */
  247.  
  248.  
  249.  
  250.  
  251. /**************************/
  252. /* Function IsVolumeFAT() */
  253. /**************************/
  254.  
  255. static int IsVolumeFAT(char *name)
  256. {
  257.     char     *tmp0;
  258.     char      rootPathName[4];
  259.     char      tmp1[MAX_PATH], tmp2[MAX_PATH];
  260.     unsigned  volSerNo, maxCompLen, fileSysFlags;
  261.  
  262.     if (isalpha(name[0]) && (name[1] == ':'))
  263.         tmp0 = name;
  264.     else
  265.     {
  266.         GetFullPathName(name, MAX_PATH, tmp1, &tmp0);
  267.         tmp0 = &tmp1[0];
  268.     }
  269.     strncpy(rootPathName, tmp0, 3);   /* Build the root path name, */
  270.     rootPathName[3] = '\0';           /* e.g. "A:/"                */
  271.  
  272.     GetVolumeInformation(rootPathName, tmp1, MAX_PATH, &volSerNo,
  273.                          &maxCompLen, &fileSysFlags, tmp2, MAX_PATH);
  274.  
  275.     if ( !strncmp(strupr(tmp2), "FAT", 3) )
  276.         return TRUE;
  277.     else
  278.         return FALSE;
  279. }
  280.  
  281.  
  282.  
  283.  
  284. /******************************/
  285. /* Function IsFileNameValid() */
  286. /******************************/
  287.  
  288. static int IsFileNameValid(char *name)
  289. {
  290.     HFILE    hf;
  291.     OFSTRUCT of;
  292.  
  293.     hf = OpenFile(name, &of, OF_READ | OF_SHARE_DENY_NONE);
  294.     if (hf == HFILE_ERROR)
  295.         switch (GetLastError())
  296.         {
  297.             case ERROR_INVALID_NAME:
  298.             case ERROR_FILENAME_EXCED_RANGE:
  299.                 return FALSE;
  300.             default:
  301.                 return TRUE;
  302.         }
  303.     else
  304.         _lclose(hf);
  305.     return TRUE;
  306. }
  307.  
  308.  
  309.  
  310.  
  311. /**********************/
  312. /* Function map2fat() */        /* Identical to OS/2 version */
  313. /**********************/